<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Db;

class Jdyalarm extends Api
{
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['*'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['*'];

    public function _initialize()
    {
        parent::_initialize();

    }

    //http://acciot.test/api/jdyalarm/addsetfordevice
    //为所有设备添加预设的警报参数
    public function addsetfordevice()
    {
        set_time_limit(0); //执行时间无限
        ini_set('memory_limit', '-1'); //内存无限
        $data0 = date('H:i:s');

        $devicemodel = new \app\admin\model\jdy\Device;
        $list = $devicemodel->field("id, room_id, name, smallcategory_id")->select();
        foreach ($list as $row) {
            $deviceset = \app\admin\model\jdy\Devicealarmset::where('device_id', $row['id'])->find();
            if (!$deviceset) {
                $deviceset = new \app\admin\model\jdy\Devicealarmset();
                $deviceset->device_id = $row['id'];
                $deviceset = $this->getRAB($row, $deviceset);

                $deviceset->warning_type = "即時告警";
                $warray = [42, 40, 39, 36, 41];
                if (in_array($row->smallcategory_id, $warray)) {
                    $deviceset->warning_type = "延時告警";
                }

                $deviceset->warning1_status = "在線";
                $warray = [40];
                if (in_array($row->smallcategory_id, $warray)) {
                    $deviceset->warning1_status = "離線";
                }

                $deviceset->warning_status = "在線";
                $warray = [42, 36];
                if (in_array($row->smallcategory_id, $warray)) {
                    $deviceset->warning_status = "離線";
                }

                $deviceset->delay_time = 0;
                $warray = [42, 40, 36, 41];
                if (in_array($row->smallcategory_id, $warray)) {
                    $deviceset->delay_time = 10;
                }

                $deviceset->replay_time = 0;
                $warray = [42, 40, 36, 46, 44];
                if (in_array($row->smallcategory_id, $warray)) {
                    $deviceset->replay_time = 10;
                }

                $deviceset->save();
            }
        }

        //echo '<br>'.$data0.' ~ ' . date('H:i:s') . '<br>';
    }

    //获取配对R的AB裝置+配对G的B装置
    //$row--device     $deviceset--set
    //清BR    ->  清BAG+清BBG
    //清BAG   ->  清BBG
    function getRAB($row, $deviceset)
    {
        if (empty($row)) {
            return $deviceset;
        }

        $name = $row['name'];
        if (empty($name)) {
            return $deviceset;
        }

        $len = strlen($name);
        if ($len < 3) {
            return $deviceset;
        }

        $R = substr($name, -1, 1);

        if ($R == "R") {
            $pre = substr($name, 0, $len - 1);
            $nameA = $pre . "AG";
            $nameB = $pre . "BG";
            $deviceA = \app\admin\model\jdy\Device::where("room_id", $row["room_id"])->where("name", $nameA)->find();
            $deviceB = \app\admin\model\jdy\Device::where("room_id", $row["room_id"])->where("name", $nameB)->find();
            if ($deviceA) {
                $deviceset['device1_id'] = $deviceA['id'];
            }
            if ($deviceB) {
                $deviceset['device2_id'] = $deviceB['id'];
            }
        } else if ($R == "G") {
            // G装置
            $deviceB = $this->getGAB($row);
            if ($deviceB) {
                $deviceset['device1_id'] = $deviceB['id'];
            }
        }
        return $deviceset;
    }

    //获取对应的G裝置代號
    function getGAB($row)
    {
        if (empty($row)) {
            return null;
        }

        $name = $row['name'];
        if (empty($name)) {
            return null;
        }

        $len = strlen($name);
        if ($len < 3) {
            return null;
        }

        $G = substr($name, -1, 1);

        if ($G == "G") {
            $A = substr($name, -2, 1);
            $B = "B"; //泵的编号 A-B泵对应
            if ($A == "B") {
                $B = "A";
            }
            $pre = substr($name, 0, $len - 2);
            $nameB = $pre . $B . "G";

            $deviceB = \app\admin\model\jdy\Device::where("room_id", $row['room_id'])->where("name", $nameB)->find();
            return $deviceB;
        }
        return null;
    }

    // http://localhost:9100//api/jdyalarm/alarmjs?deviceid=1
    // http://mg.acciot.com.tw/api/jdyalarm/alarmjs?deviceid=1
    // 即时警示
    public function alarmjs($deviceid)
    {
        set_time_limit(0); //执行时间无限
        ini_set('memory_limit', '-1'); //内存无限

        // 只取一个传入参数为deviceid最新发生的log
        $sql = "select d.id as deviceid, d.smallcategory_id, d.name as devicename, d.selfname as deviceselfname,";
        $sql .= " d.online as deviceonline, d.online_starttime, ac.id as anchang_id, ac.name as acname, ac.room_id, da.*";
        $sql .= " from fa_jdy_device d inner join fa_jdy_anchang ac on d.room_id = ac.room_id ";
        $sql .= " inner join fa_jdy_devicealarmset da on d.id = da.device_id ";
        $sql .= "WHERE d.id = " . (string)$deviceid;
        $devicelist = Db::query($sql);
        foreach ($devicelist as $row) {
            // 为了加快速度，不在数据库查询中，单独判断
            if(!($row["warning_switch"] == '開啟' && $row["warning_type"] == '即時告警'))
            {
                continue;
            }

            if($row["smallcategory_id"] == 39 && $row["warning_way"] == "進階設置")  // G设备
            {
                break;
            }

            // 一般设备W暂时不处理
            if ($row["smallcategory_id"] == 36)
            {
                continue;
            }

            $needalarm = false; // 是否需要报警
            //先判断当前状态是不是也是“報警狀態”相同？
            if($row["warning_status"] == "在線" and $row["deviceonline"] == 1)
            {
                $needalarm = true;
            }
            if($row["warning_status"] == "離線" and $row["deviceonline"] == 0)
            {
                $needalarm = true;
            }

            if($needalarm)
            {
                //暂定1天之内24*3600没有播报过的，就要播报  ！！！！！
                $news = \app\admin\model\jdy\News::where('device_id', $deviceid)
                    ->where("create_time", ">=", date('Y-m-d H:i:s', time()-24*3600))->find();
                if (!$news)
                {
                    // 写入fa_jdy_news数据库
                    $this->writeNewsJS($row);
                }
            }
        }
        //echo "alarmjs finished";
    }

    // http://localhost:9100//api/jdyalarm/alarmys
    // http://mg.acciot.com.tw/api/jdyalarm/alarmys
    // 延时警示，每分钟调用一次延时播报
    public function alarmys()
    {
        set_time_limit(0); //执行时间无限
        ini_set('memory_limit', '-1'); //内存无限

        //$starttimeInit = strtotime("2020-03-23 17:30:00")-60; //测试前一分钟
        $starttimeInit = time();

        // 设备信息和案场信息
        $sql = "select d.id as deviceid, d.smallcategory_id, d.name as devicename, d.selfname as deviceselfname,";
        $sql .= " d.room_id, d.online, d.online_starttime, ac.id as anchang_id, ac.name as acname, da.*";
        $sql .= " from fa_jdy_device d inner join fa_jdy_anchang ac on d.room_id = ac.room_id";
        $sql .= " inner join fa_jdy_devicealarmset da on d.id = da.device_id";
        $sql .= " where d.online_starttime != 0";
        $device_list = Db::query($sql);

        // 该列表是保存已经查找过的列表，为了防止重复写入
        $haveWritetoNewsDeviceIDArray = array();
        foreach ($device_list as $row) {
            // 为了加快速度，不在数据库查询中，单独判断
            if(!($row["warning_switch"] == '開啟' && $row["warning_type"] == '延時告警'))
            {
                continue;
            }

            // 一般设备W与G设备都不做延时处理
            if ($row["smallcategory_id"] == 36 || $row["smallcategory_id"] == 39 )
            {
                continue;
            }

            // 说明已经查询过了，直到再找到新的一个deviceid
            if(in_array($row["deviceid"], $haveWritetoNewsDeviceIDArray))
            {
                continue;
            }

            // ~test01
//            $array_id = array(268);
//            if( !in_array($row["deviceid"], $array_id))
//            {
//                continue;
//            }
            // ~test01

            $needalarm = false; // 是否需要报警
            //先判断当前状态是不是也是“報警狀態”相同？
            if($row["warning_status"] == "在線" and $row["online"] == 1)
            {
                $needalarm = true;
            }
            if($row["warning_status"] == "離線" and $row["online"] == 0)
            {
                $needalarm = true;
            }
            // 判断状态是否持续了 延迟时间长 delay_time
            if( time() - $row["online_starttime"] <= $row["delay_time"]*60 )
            {
                $needalarm = false;
            }

            if($needalarm)
            {
                //先取$row["delay_time"]延遲時間前的最后一次的状态，是不是也是“報警狀態”相同？
                // 非一般设备R，只要判断自身即可，不需要判断关联设备RAG，RBG
                if($row["smallcategory_id"] != 40)
                {
                    // 再判断是不是在$row["delay_time"]延迟时间内已经播报过？按ID降序排列，找到最后生成的ID，判断是否满足条件？
                    $news = \app\admin\model\jdy\News::where('device_id', $row['deviceid'])
                        ->order('id', 'desc')->find();
                    if (!$news)
                    {
                        // 没有，就要写入
                        // 写入fa_jdy_news数据库
                        $this->writeNewsYS($row,  -1, -1, 0);
                        // 已经播报了，不用再判断重复
                        continue;
                    }

                    // 有重复播报要求
                    if($row["replay_time"] > 0)
                    {
                        // 判断是不是在$row["replay_time"]重複報警時間(小時)内已经播报过？
                        $news = \app\admin\model\jdy\News::where('device_id', $row['deviceid'])->order('id', 'desc')
                            ->where("create_time", ">=", date('Y-m-d H:i:s', time()- $row["replay_time"]*3600))->find();
                        echo 'Judge replay_time?' . '<br />';
                        if(!$news)
                        {
                            // 在$row["replay_time"]重複報警時間(小時)内，没有播报，就要再播报一次
                            // 写入fa_jdy_news数据库
                            $this->writeNewsYS($row,  -1, -1, 0);
                        }
                    }
                }
                else
                {
                    // R 设备
                    // R 裝置的提醒，還要再增加跟兩個關聯裝置，只要其中之一有同步，就不需要報警
                    // 先device1 RAG判断
                    if($row["device1_id"] !=0)
                    {
                        $Device1 = \app\admin\model\jdy\Device::where('device_id', $row["device1_id"])->find();
                        // 判断状态是否持续了 延迟时间长 delay_time
                        if( time() - $Device1["online_starttime"] <= $row["delay_time"]*60 )
                        {
                            $needalarm = false;
                        }
                        else
                        {
                            if(!($row["warning1_status"] == "在線" and $Device1["online"] == 1))
                            {
                                $needalarm = false;
                            }
                            if(!($row["warning1_status"] == "離線" and $Device1["online"] == 0))
                            {
                                $needalarm = false;
                            }
                        }
                        // 追加到查找列表中
                        array_push($haveWritetoNewsDeviceIDArray, $row["device1_id"]);
                    }

                    // 再device2 RBG判断，如果有
                    if($row["device2_id"] !=0)
                    {
                        $Device2 = \app\admin\model\jdy\Device::where('device_id', $row["device2_id"])->find();
                        // 判断状态是否持续了 延迟时间长 delay_time
                        if( time() - $Device2["online_starttime"] <= $row["delay_time"]*60 )
                        {
                            $needalarm = false;
                        }
                        else
                        {
                            if(!($row["warning1_status"] == "在線" and $Device2["online"] == 1))
                            {
                                $needalarm = false;
                            }
                            if(!($row["warning1_status"] == "離線" and $Device2["online"] == 0))
                            {
                                $needalarm = false;
                            }
                        }
                        // 追加到查找列表中
                        array_push($haveWritetoNewsDeviceIDArray, $row["device2_id"]);
                    }

                    if($needalarm == false)
                        continue;

                    // 判断是不是在$row["delay_time"]延迟时间内已经播报过？
                    $news = \app\admin\model\jdy\News::where('device_id', $row['deviceid'])
                        ->order('id', 'desc')->find();
                    // 判断同時告警狀態$row["warning1_status"]是否相同？
                    if (!$news)
                    {
                        // 没有，就要写入
                        // 再判断关联的RAG、RBG设备条件满不满足？
                        foreach ($device_list as $device_row)
                        {
                            // 查找RAG,RBG，判断关联设备同時告警狀態$row["warning1_status"]是否相同？
                            // 一定有RAG，但不一定有RBG
                            if($row["device1_id"] !=0 and $row["device1_id"] == $device_row["id"])
                            {
                                // 有RAG关联设备
                                // 判断是不是 状态相同？如果不同，就不播报
                                if($row["warning1_status"] == "在線" and $device_row["online"] == 0)  // 不同
                                {
                                    $needalarm = false;
                                }
                                if($row["warning1_status"] == "離線" and $device_row["online"] == 1)  // 不同
                                {
                                    $needalarm = false;
                                }

                                if($needalarm and $row["device2_id"] !=0)
                                {
                                    foreach ($device_list as $device2_row)
                                    {
                                        // 再判断有没有RBG设备，满不满足状态？
                                        if($row["device2_id"] == $device2_row["id"])
                                        {
                                            // 有RAG关联设备
                                            // 判断是不是 状态相同？如果不同，就不播报
                                            if($row["warning1_status"] == "在線" and $device2_row["online"] == 0)  // 不同
                                            {
                                                $needalarm = false;
                                            }
                                            if($row["warning1_status"] == "離線" and $device2_row["online"] == 1)  // 不同
                                            {
                                                $needalarm = false;
                                            }
                                            break;
                                        }
                                    }
                                }
                                break;
                            }
                        }

                        if($needalarm)
                        {
                            //查找关联设备的名称和状态
                            // 取最后该ID的name和状态online，为了后面关联设备写入信息时，要写入关联设备的名称和即时状态
                            // 先取device1的名称name和即时状态online
                            $row["device1_name"] = "";
                            $row["device1_status"] = "";
                            $device1Row = \app\admin\model\jdy\Device::where("id", $row['device1_id'])->find();
                            if ($device1Row) {
                                $row["device1_status"] = $device1Row["online"] == 1? "在線" : "離線";
                                // 清AG、清BG只要其中一個跟清R有同步，不需要告警!
                                if($device1Row["device1_status"] == $row["warning_status"])
                                    continue;
                                $row["device1_name"] = $device1Row["name"];
                            }
                            // 写入数据库
                            if($row["device2_id"] != 0) // 有2个关联设备未同步
                            {
                                $device2Row = \app\admin\model\jdy\Device::where("id", $row["device2_id"])->find();
                                if ($device2Row) {
                                    $row["device2_status"] = $device2Row["online"] == 1? "在線" : "離線";
                                    // 清AG、清BG只要其中一個跟清R有同步，不需要告警!
                                    if($device2Row["device2_status"] == $row["warning_status"])
                                        continue;
                                    $row["device2_name"] = $device2Row["name"];
                                }
                                $this->writeNewsYS($row, -1, 5, 0);
                            }
                            else
                            {
                                $this->writeNewsYS($row, -1, 6, 0);
                            }
                            // 已经播报了，不用再判断重复
                            continue;
                        }
                    }
                    // 有重复播报要求
                    if($row["replay_time"] > 0)
                    {
                        // 首先有
                        // 再判断是不是在$row["replay_time"]重複報警時間(小時)内已经播报过？
                        $news = \app\admin\model\jdy\News::where('device_id', $row['deviceid'])->order('id', 'desc')
                            ->where("create_time", ">=", date('Y-m-d H:i:s', time()- $row["replay_time"]*3600))->find();
                        if(!$news)
                        {
                            // 在$row["replay_time"]重複報警時間(小時)内，没有播报，就要再播报一次
                            // 写入fa_jdy_news数据库
                            $this->writeNewsYS($row,  -1, -1, 0);
                            continue;
                        }
                    }
                }
                // 查询结束
            }
        }
        //echo "alarmys finished";
    }

    // 输入参数$section：0-> 05:00:00调用   1-> 13:00:00调用  2-> 21:00:00调用
    // 只有G设备，而且設置方式是：進階設置，调用三个时间段的
    // http://localhost:9100//api/jdyalarm/Alarm3Sections?section=0
    // http://mg.acciot.com.tw/api/jdyalarm/Alarm3Sections?section=0
    public function Alarm3Sections($section){
        if ($section != 0 and $section != 1 and $section != 2)
        {
            return;
        }
        set_time_limit(0); //执行时间无限
        ini_set('memory_limit', '-1'); //内存无限

        // 只有在第1个section0-> 05:00:00，才判断标准值开启时的次数，要向前查找1天内的对应的device
        // 在第2和第3个section阶段，要向前查找8小时内的对应的device
        // 每个对应的device要状态转换一次，才算1次，即开关一次才算一次。
        // 先判断今天是周几？以此来决定是取【d0~d6】的哪一段？
        $whatdayistoday = date("w",time());    // 周几？从0开始，0代表周日，1代表周1，以此类推，6代表周六
        $starttimePre = null;
        $starttimeNext = null;

        switch ($section)
        {
            case 0: // 0：找前8小时内的
                $starttimeNext = strtotime("05:00:00");
                $starttimePre = $starttimeNext - 8*3600;
                break;
            case 1: // 1：找前8小时内的
                $starttimeNext = strtotime("13:00:00");
                $starttimePre = $starttimeNext - 8*3600;
                break;
            default: // 2： 找前8小时内的
                $starttimeNext = strtotime("21:00:00");
                $starttimePre = $starttimeNext - 8*3600;
                break;
        }
        // 24小时开始时间
        $starttimePre24 = $starttimeNext - 24*3600;

        // 1、取得所有的G设备的device。online_starttime不为0，才有效
        $sql = "select d.id as deviceid, d.smallcategory_id, d.name as devicename, d.selfname as deviceselfname,";
        $sql .= " d.online as deviceonline, d.online_starttime, ac.name as acname, ac.room_id ,da.*";
        $sql .= " from fa_jdy_device d inner join fa_jdy_anchang ac on d.room_id = ac.room_id";
        $sql .= " inner join fa_jdy_devicealarmset da on d.id = da.device_id";
        $sql .= " where d.online_starttime != 0 and d.smallcategory_id = 39 and da.warning_way = '進階設置'";
        // 取得在时间段内所有的发生状态的devicelog
        $Alldevicelist = Db::query($sql);

        // 2、再取得在24小时时间段内所有的发生状态的devicelog，为了后面查找。按设备ID和发生时间升序排列，因为下限值的判断是24小时间隔
        $sql = "select device_id, online, starttime";
        $sql .= " from fa_jdy_devicelog";
        $sql .= " WHERE starttime >= $starttimePre24 or starttime <= $starttimeNext";
        $sql .= " ORDER BY device_id, starttime";
        // 取得在时间段内所有的发生状态的devicelog
        $Alldevicelog_List = Db::query($sql);

        // 定义d?_array数组，保存提取的d0-d6的组合
        $dnum_array = array("dnum_tnum"=>0, "dnum_standard_switch"=>"關閉",
            "dnum_standard"=>0, "dnum_top"=>0, "dnum_online"=>0, "dnum_offline"=>0);
        // 在所有的时间内的状态分别做判断，判断是否满足规格的状态变化要求
        $haveWritetoNewsDeviceIDArray = array();    // 该列表是保存已经查找过的列表，为了防止重复写入
        // 在设备列表中依次循环判断
        //$num = 0;
        foreach ($Alldevicelist as $row)
        {
            // ~test01
//            $array_id = array(156,161,167,177,187);
//            if( !in_array($row["deviceid"], $array_id))
//            {
//                continue;
//            }
            // ~test01

            if(!($row["smallcategory_id"] == 39 and $row["warning_way"] == '進階設置'))
                continue;

            // 说明已经查询过了，直到再找到新的一个deviceid
            if(in_array($row["deviceid"], $haveWritetoNewsDeviceIDArray))
            {
                continue;
            }

            // 先将该设备对应的G设备加入列表，以防重复处理
            if ($row["device1_id"] != 0) {
                // 追加到查找列表中
                array_push($haveWritetoNewsDeviceIDArray, $row["device1_id"]);
            }

            // 直接赋值，将当前天是周几的相关值取出
            $dnum_array["dnum_tsection"] = $row["d".$whatdayistoday."_t".(string)($section+1)]; // 下限值
            $dnum_array["dnum_standard_switch"] = $row["d".$whatdayistoday."_standard_switch"]; // 标准值开关
            $dnum_array["dnum_standard"] = $row["d".$whatdayistoday."_standard"];   // 标准值次数
            $dnum_array["dnum_top"] = $row["d".$whatdayistoday."_top"]; // 上限值
            $dnum_array["dnum_online"] = $row["d".$whatdayistoday."_online"];   // 在線狀態
            $dnum_array["dnum_offline"] = $row["d".$whatdayistoday."_offline"]; // 離線狀態

            $online_count = 0;  // 在线的次数
            $offline_count = 0;  // 离线的次数
            $pretimeCusor = $starttimePre;  // 前一次状态切换的时间点，用于计算状态切换的时间跨度
            // 统计标准值是否未达到？
            // 只有设置了标准值次数且标准值开关开启，才要判断
            if ($dnum_array["dnum_standard_switch"] == "開啟" and $dnum_array["dnum_standard"] > 0)
            {
                // 要判断前一天24小时之内有没有低于标准值
                $predevicestatus = -1;  // 前一次的状态，状态切换必须是交替的，如果是连续变化，不算一次
                foreach ($Alldevicelog_List as $devicelog_row) {
                    //不在24小时内，就不处理，默认就是24小时内，所以不用判断
                    //if($devicelog_row["starttime"]<$starttimePre24)
                    //continue;

                    // 判断有没有
                    if ($devicelog_row["device_id"] == $row["deviceid"] or $devicelog_row["device_id"] == $row["device1_id"])
                    {
                        // 只能交替变化才可以
                        if($predevicestatus == -1)
                        {
                            // 初始第一次不计算
                            $predevicestatus = $devicelog_row["online"];
                            $pretimeCusor = $devicelog_row["starttime"];
                        }
                        else
                        {
                            // 在线
                            if($devicelog_row["online"] == 1)
                            {
                                // 判断一个状态切换时间跨度是不是超过标准值？
                                if($predevicestatus == 0)
                                {
                                    // 状态切换了
                                    if($devicelog_row["starttime"] - $pretimeCusor > $dnum_array["dnum_online"]*60)   // 单位是秒
                                    {
                                        $online_count++;
                                    }
                                    // 要更新状态和前时间点
                                    $pretimeCusor = $devicelog_row["starttime"];
                                    $predevicestatus = $devicelog_row["online"];
                                }
                            }
                            else    // 离线
                            {
                                // 判断一个状态切换时间跨度是不是超过标准值？
                                if($predevicestatus == 1)
                                {
                                    // 状态切换了
                                    if($devicelog_row["starttime"] - $pretimeCusor > $dnum_array["dnum_offline"]*60)   // 单位是秒
                                    {
                                        // 已经低于下限，且状态变化了
                                        $offline_count++;
                                    }
                                    // 更新状态和前时间点
                                    $pretimeCusor = $devicelog_row["starttime"];
                                    $predevicestatus = $devicelog_row["online"];
                                }
                            }
                        }
                    }

                    // 如果次数都超过了标准值，就要退出
                    // 且在线和离线次数都不是初始值0
                    if ($online_count != 0 and $offline_count != 0 and
                        $online_count > $dnum_array["dnum_standard"] and $offline_count > $dnum_array["dnum_standard"])
                    {
                        // 取大值
                        $noReachMaxNum = $online_count > $offline_count ? $online_count : $offline_count;
                        // 判断是否重复？
                        // 要判断news里，是不是已经保存过了？
                        //暂定1天之内24*3600没有播报过的，就要播报  ！！！！！
                        $news = \app\admin\model\jdy\News::where('device_id', $row['id'])->where('type','裝置狀態')
                            ->where("create_time", ">=", date('Y-m-d H:i:s', time()-24*3600))->find();
                        if(!$news)   // 没有
                        {
                            // 写入警告信息到=>news数据库，0代表标准值未达标
                            $this->writeNewsYS($row, $section, 0, $noReachMaxNum);
                        }
                        break;  // 跳出标准值的判断
                    }
                }
            }

            // 下限值设置大于0，才有必要判断
            if($dnum_array["dnum_top"] > 0)
            {
                // 标准值开关开启或关闭，以下都要判断
                // 依次判断在8小时时间段，满足deviceid相同且满足在線/離線時間状态值的个数，是否满足下限值。
                $online_count = 0;  // 在线的次数
                $offline_count = 0;  // 离线的次数
                $predevicestatus = -1;  // 前一次的状态，状态切换必须是交替的，如果是连续变化，不算一次
                $pretimeCusor = $starttimePre;  // 前一次状态切换的时间点，用于计算状态切换的时间跨度
                foreach ($Alldevicelog_List as $devicelog_row)
                {
                    // 默认是24小时内，所以在8小时内，就要处理，排除8小时以外的
                    if($devicelog_row["starttime"] < $starttimePre)
                        continue;

                    if($devicelog_row["device_id"] == $row["deviceid"] or $devicelog_row["device_id"] == $row["device1_id"])
                    {
                        // 只能交替变化才可以
                        if($predevicestatus == -1)
                        {
                            // 初始第一次不计算
                            $pretimeCusor = $devicelog_row["starttime"];
                            $predevicestatus = $devicelog_row["online"];
                        }
                        else
                        {
                            // 在线
                            if($devicelog_row["online"] == 1)
                            {
                                // 判断一个状态切换时间跨度是不是低于下限值？？
                                if($predevicestatus == 0)
                                {
                                    if($devicelog_row["starttime"] - $pretimeCusor < $dnum_array["dnum_online"]*60)   // 单位是秒
                                    {
                                        $online_count++;
                                    }
                                    // 要更新状态和前时间点
                                    $pretimeCusor = $devicelog_row["starttime"];
                                    $predevicestatus = $devicelog_row["online"];
                                }
                            }
                            else    // 离线
                            {
                                // 判断一个状态切换时间跨度是不是低于下限值？？
                                if($predevicestatus == 1)
                                {
                                    if($devicelog_row["starttime"] - $pretimeCusor < $dnum_array["dnum_offline"]*60)   // 单位是秒
                                    {
                                        $online_count++;
                                    }
                                    // 要更新状态和前时间点
                                    $pretimeCusor = $devicelog_row["starttime"];
                                    $predevicestatus = $devicelog_row["online"];
                                }
                            }
                        }
                    }

                    // 如果在线和离线次数都低于下限值，就要报警
                    // 且在线和离线次数都不是初始值0
                    if ($online_count != 0 and $offline_count != 0 and
                        $online_count < $dnum_array["dnum_tsection"] and $offline_count < $dnum_array["dnum_tsection"])
                    {
                        // 取小值
                        //echo "未到下限值11111" . $dnum_array["dnum_tsection"] . "  :" . $online_count . "   " . $dnum_array["dnum_tsection"] . "   :".  $offline_count ."<br>";

                        $noReachMinNum = $online_count < $offline_count ? $online_count : $offline_count;
                        // 写入警告信息到=>news数据库，1代表下限值未达标
                        // 要判断news里，是不是已经保存过了？
                        //暂定1天之内24*3600没有播报过的，就要播报  ！！！！！
                        $news = \app\admin\model\jdy\News::where('device_id', $row['id'])->where('type','裝置狀態')
                            ->where("create_time", ">=", date('Y-m-d H:i:s', time()-24*3600))->find();
                        if(!$news)   // 没有
                        {
                            $this->writeNewsYS($row, $section, 1, $noReachMinNum);
                        }
                        break;  // 跳出是否满足下限值的判断
                    }
                }
            }

            // 上限值设置大于0，才有必要判断
            if($dnum_array["dnum_top"] > 0)
            {
                // 依次判断在24小时时间段，满足deviceid相同且满足在線/離線時間状态值的个数，是否满足上限值。
                $online_count = 0;  // 在线的次数
                $offline_count = 0;  // 离线的次数
                $predevicestatus = -1;  // 前一次的状态，状态切换必须是交替的，如果是连续变化，不算一次
                $pretimeCusor = $starttimePre24;  // 前一次状态切换的时间点，用于计算状态切换的时间跨度
                foreach ($Alldevicelog_List as $devicelog_row)
                {
                    if($devicelog_row["device_id"] == $row["deviceid"] or $devicelog_row["device_id"] == $row["device1_id"])
                    {
                        // 只能交替变化才可以
                        if($predevicestatus == -1)
                        {
                            // 初始第一次不计算
                            $pretimeCusor = $devicelog_row["starttime"];
                            $predevicestatus = $devicelog_row["online"];
                        }
                        else
                        {
                            // 在线
                            if($devicelog_row["online"] == 1)
                            {
                                if($predevicestatus == 0)
                                {
                                    // 已经超过上限，且状态变化了
                                    if($devicelog_row["starttime"] - $pretimeCusor > $dnum_array["dnum_online"]*60)   // 单位是秒
                                    {
                                        $online_count++;
                                    }
                                    // 更新状态和前时间点
                                    $pretimeCusor = $devicelog_row["starttime"];
                                    $predevicestatus = $devicelog_row["online"];
                                }
                            }
                            else    // 离线
                            {
                                if($predevicestatus == 1)
                                {
                                    // 已经超过上限，且状态变化了
                                    if($devicelog_row["starttime"] - $pretimeCusor > $dnum_array["dnum_offline"]*60)   // 单位是秒
                                    {
                                        $offline_count++;
                                    }
                                    // 更新状态和前时间点
                                    $pretimeCusor = $devicelog_row["starttime"];
                                    $predevicestatus = $devicelog_row["online"];
                                }
                            }
                        }

                        // 如果在线和离线次数都大于上限值，就要报警
                        // 且在线和离线次数都不是初始值0
                        if ($online_count != 0 and $offline_count != 0 and
                            $online_count > $dnum_array["dnum_top"] and $offline_count > $dnum_array["dnum_top"])
                        {
                            // 取小值
                            $noReachMaxNum = $online_count > $offline_count ? $online_count : $offline_count;
                            // 写入警告信息到=>news数据库，2代表超过上限值
                            // echo "超过上限值" . "<br>";
                            // 要判断news里，是不是已经保存过了？
                            //暂定1天之内24*3600没有播报过的，就要播报  ！！！！！
                            $news = \app\admin\model\jdy\News::where('device_id', $row['id'])->where('type','裝置狀態')
                                ->where("create_time", ">=", date('Y-m-d H:i:s', time()-24*3600))->find();
                            if(!$news)   // 没有
                            {
                                $this->writeNewsYS($row, $section, 2, $noReachMaxNum);
                            }
                            break;  // 跳出是否满足在线和离线次数都大于上限值
                        }
                    }
                }
            }

            // 依次判断在24小时时间段，是否有運轉不足（即在线时间不足 在線狀態时长）和待機不足（即离线时间不足 離線狀態 时长）
            // 以上两种情况，有一次发生就报警
            $bHasWriteOnline = false;  // 已经写入一次 運轉不足（即在线时间不足 在線狀態时长）
            $bHasWriteOffline = false;  // 已经写入一次 待機不足（即离线时间不足 離線狀態 时长）
            $predevicestatus = -1;  // 前一次的状态，状态切换必须是交替的，如果是连续变化，不算一次
            $pretimeCusor = $starttimePre24;  // 前一次状态切换的时间点，用于计算状态切换的时间跨度
            foreach ($Alldevicelog_List as $devicelog_row)
            {
                if($devicelog_row["device_id"] == $row["deviceid"] or $devicelog_row["device_id"] == $row["device1_id"])
                {
                    // 只能交替变化才可以
                    if($predevicestatus == -1)
                    {
                        // 初始第一次不计算
                        $pretimeCusor = $devicelog_row["starttime"];
                        $predevicestatus = $devicelog_row["online"];
                    }
                    else
                    {
                        // 在线
                        if($devicelog_row["online"] == 1)
                        {
                            if($predevicestatus == 0)
                            {
                                // 已经超过上限，且状态变化了
                                if($dnum_array["dnum_online"] > 0 and $devicelog_row["starttime"] - $pretimeCusor < $dnum_array["dnum_online"]*60)   // 单位是秒
                                {
                                    $bHasWriteOnline = true;
                                    // echo "运转不足" . "<br>";
                                    // 要判断news里，是不是已经保存过了？
                                    //暂定1天之内24*3600没有播报过的，就要播报  ！！！！！
                                    $news = \app\admin\model\jdy\News::where('device_id', $row['id'])->where('type','裝置狀態')
                                        ->where("create_time", ">=", date('Y-m-d H:i:s', time()-24*3600))->find();
                                    if(!$news)   // 没有
                                    {
                                        //echo "临时关闭运转不足" . "<br>";
                                        $bHasWriteOnline = true;
                                        // $this->writeNewsYS($row, $section, 3, 0);
                                    }
                                }
                                // 更新状态和前时间点
                                $pretimeCusor = $devicelog_row["starttime"];
                                $predevicestatus = $devicelog_row["online"];
                            }
                        }
                        else    // 离线
                        {
                            if($predevicestatus == 1)
                            {
                                // 已经超过上限，且状态变化了
                                if($dnum_array["dnum_offline"] > 0 and $devicelog_row["starttime"] - $pretimeCusor < $dnum_array["dnum_offline"]*60)   // 单位是秒
                                {
                                    $bHasWriteOffline = true;
                                    // echo "待機不足" . "<br>";
                                    // 要判断news里，是不是已经保存过了？
                                    //暂定1天之内24*3600没有播报过的，就要播报  ！！！！！
                                    $news = \app\admin\model\jdy\News::where('device_id', $row['id'])->where('type','裝置狀態')
                                        ->where("create_time", ">=", date('Y-m-d H:i:s', time()-24*3600))->find();
                                    if(!$news)   // 没有
                                    {
                                        $this->writeNewsYS($row, $section, 4, 0);
                                    }
                                }
                                // 更新状态和前时间点
                                $pretimeCusor = $devicelog_row["starttime"];
                                $predevicestatus = $devicelog_row["online"];
                            }
                        }
                    }

                    if($bHasWriteOnline and $bHasWriteOffline)
                    {
                        // 在线和离线的时间长都判断过至少一次了，就退出
                        break;
                    }
                }
            }
//            echo $num . "<br>";
//            if($num > 200)
//                return;
        }   // 设备列表中依次循环判断结束
        //echo "alarm3section end";
    }

    // http://localhost:9100//api/jdyalarm/alarmtask
    // http://mg.acciot.com.tw/api/jdyalarm/alarmtask
    // 工作警示，每天调用一次判断是否要 工作提醒(fa_jdy_task)？
    public function alarmtask()
    {
        set_time_limit(0); //执行时间无限
        ini_set('memory_limit', '-1'); //内存无限

//        $currentdateYMD = date('Y-m-d',1585584000); //测试1574438400代表2020-02-16 00:00:00
//        $currentdatePre7daysYMD = date('Y-m-d',1584979200);
//        $currentdateNext3daysYMD = date('Y-m-d', 1585929600);
        $currentdateYMD = date('Y-m-d');
        $currentdatePre7daysYMD = date('Y-m-d', time()-7*24*3600);
        $currentdateNext3daysYMD = date('Y-m-d', time()+3*24*3600);

        // 1、取得所有的当前日期以后所有工作事项的记录。前7后3天都要包含
        $sql = "select t.*, ac.name as acname";
        $sql .= " from fa_jdy_task t inner join fa_jdy_anchang ac on t.anchang_id = ac.id";
        $sql .= " where t.remind_date >= " . "'" . $currentdatePre7daysYMD . "'" .
            " and t.remind_date <= " . "'" . $currentdateNext3daysYMD. "'" . " and t.task_status <> '已結案'";
        // 取得在时间段内所有的发生状态的devicelog
        $Alltasklist = Db::query($sql);
        //echo json_encode($Alltasklist) . "<br>";

        foreach ($Alltasklist as $task_row)
        {
            if($task_row['remind_type'] == '不提醒')
            {
                continue;
            }
            else if($task_row['remind_type'] == '一般件單日提醒')
            {
                // 只到提醒日期remind_date才提醒一次
                if($task_row['remind_date'] == $currentdateYMD)
                {
                    // 要判断news里，是不是已经保存过了？
                    $newslog = \app\admin\model\jdy\News::where('task_id', $task_row['id'])->where('type','工作提醒')->find();
                    // 如果为空
                    if (!$newslog) {
                        $task_row['alarmtime'] = $currentdateYMD;
                        // 写入
                        $this->writeNewstask($task_row);
                    }
                }
            }
            else if($task_row['remind_type'] == '一般件多日提醒')
            {
                // 在指定提醒日期remind_date之前7天後3天每天都要提醒
//                if( $currentdateYMD >= date('Y-m-d', strtotime($task_row['remind_date'])-7*24*3600) &&
//                    $currentdateYMD <= date('Y-m-d', strtotime($task_row['remind_date'])+3*24*3600) )
                {
                    // 要判断news里，是不是已经保存过了？
//                    $newslog = \app\admin\model\jdy\News::where('task_id', $task_row['id'])->where('type','工作提醒')
//                        ->where('lastdevicestarttime', strtotime($currentdateYMD))->find();
                    $newslog = \app\admin\model\jdy\News::where('task_id', $task_row['id'])->where('type','工作提醒')
                        ->where('lastdevicestarttime', strtotime(date('Y-m-d')))->find();
//                    $newslog = \app\admin\model\jdy\News::where('task_id', $task_row['id'])->where('type','工作提醒')
//                        ->where('lastdevicestarttime', strtotime(date("2020-03-31")))->find();
                    //echo '判断是否存在' . "<br>";
                    // 如果为空
                    if (!$newslog) {
                        // 没有写入过，要写入
                        //echo '要写入' . "<br>";
                        $task_row['alarmtime'] = $currentdateYMD;
                        // 写入
                        $this->writeNewstask($task_row);
                    }
                }
            }
            else if($task_row['remind_type'] == '急件')
            {
                // 在指定提醒日期remind_date之前3天后每天都要提醒
                if( $currentdateYMD >= date('Y-m-d', strtotime($task_row['remind_date'])-3*24*3600) &&
                    $currentdateYMD <= date('Y-m-d', strtotime($task_row['remind_date'])) )
                {
                    // 要判断news里，是不是已经保存过了？
                    $newslog = \app\admin\model\jdy\News::where('task_id', $task_row['id'])->where('type','工作提醒')
                        ->where('lastdevicestarttime',strtotime($currentdateYMD))->find();
                    // 如果为空
                    if (!$newslog) {
                        // 没有写入过，要写入
                        $task_row['alarmtime'] = $currentdateYMD;
                        // 写入
                        $this->writeNewstask($task_row);
                    }
                }
            }

            // 重复提醒日期
            if($task_row["replay"] > 0)
            {
                $news = \app\admin\model\jdy\News::where('task_id', $task_row['id'])->find();
                if($news)
                {
                    // 首先有
                    // 再判断是不是在$task_row["replay"]重複報警日期(天)内已经播报过？
                    $news = \app\admin\model\jdy\News::where('task_id', $task_row['id'])
                        ->where("create_time", ">=", date('Y-m-d H:i:s',
                            strtotime($currentdateYMD)-$task_row["replay"]*24*3600))->find();
                    if(!$news)
                    {
                        // 在$row["replay_time"]重複報警時間(小時)内，没有播报，就要再播报一次
                        // 写入fa_jdy_news数据库
                        $this->writeNewstask($task_row);
                    }
                }
            }
        }
        //echo "alarmtask finish!";
    }

    // http://localhost:9100//api/jdyalarm/alarmheyue
    // http://mg.acciot.com.tw/api/jdyalarm/alarmheyue
    // 合约警示，每月1日调用一次判断是否要 合约提醒(fa_jdy_heyue)？
    public function alarmheyue()
    {
        //$currentdateYMD = date('Y-m-d',1574998323); //测试1574438400代表2019-11-23 00:00:00
        //echo $currentdateYMD;
        //return;
        set_time_limit(0); //执行时间无限
        ini_set('memory_limit', '-1'); //内存无限

        $currentdateYMD = date('Y-m-d');

        // 2、取得所有的当前日期以后所有合约的记录。
        $sql = "select hy.*, ac.name as acname";
        $sql .= " from fa_jdy_heyue hy inner join fa_jdy_anchang ac on hy.anchang_id = ac.id";
        // $sql .= " where hy.remind_start_date >= '" . $currentdateYMD . "'";
        // 取得在时间段内所有的发生状态的devicelog
        $Allheyuelist = Db::query($sql);

        // 合约事项提醒
        // 如果当前是1号，才做合约判断
        foreach ($Allheyuelist as $heyue_row)
        {
            // 在指定提醒日期合约开始日（remind_start_date）之前7天後3天每天都要提醒
            if( $currentdateYMD >= date('Y-m-d', strtotime($heyue_row['remind_start_date'])-7*24*3600) &&
                $currentdateYMD <= date('Y-m-d', strtotime($heyue_row['remind_start_date'])+3*24*3600) )
            {
                // 先判断是不是已经写入了？
                $newslog = \app\admin\model\jdy\News::where('heyue_id', $heyue_row['id'])->where('type','工作提醒')
                    ->where('lastdevicestarttime', strtotime(date('Y-m-d')))->find();
                // 如果为空
                if (!$newslog) {
                    // 写入
                    $this->writeNewsheyue($heyue_row, 1);
                }
            }

            // 接着判断，因为合约开始和结束日期有的可能比较窄，在指定提醒日期合約日期結束（remind_end_date）之前7天後3天每天都要提醒
            if( $currentdateYMD >= date('Y-m-d', strtotime($heyue_row['remind_end_date'])-7*24*3600) &&
                $currentdateYMD <= date('Y-m-d', strtotime($heyue_row['remind_end_date'])+3*24*3600) )
            {
                // 先判断是不是已经写入了？
                $newslog = \app\admin\model\jdy\News::where('heyue_id', $heyue_row['id'])->where('type','工作提醒')
                    ->where('lastdevicestarttime', strtotime(date('Y-m-d')))->find();
                // 如果为空
                if (!$newslog) {
                    // 写入
                    $this->writeNewsheyue($heyue_row, 2);
                }
            }
//                else {
//                    // 先取月
//                    $month = (int)date('m', $heyue_row['remind_end_date']);
//                    $year = (int)date('Y', $heyue_row['remind_end_date']);
//                    if($month == 1)    // 前一个月就是上一年的12月
//                    {
//                        if(date('Y-m') == (string)($year-1).'-12')
//                        {
//                            // 先判断是不是已经写入了？
//                            $newslog = \app\admin\model\jdy\News::where('heyue_id', $heyue_row['id'])->where('type','工作提醒')
//                                ->where('lastdevicestarttime', strtotime(date('Y-m-d')))->find();
//                            // 如果为空
//                            if (!$newslog) {
//                                // 写入
//                                $this->writeNewsheyue($heyue_row, 2);
//                            }
//                        }
//                    }
//                    else{   // 是不是同一年的前一个月
//                        if(date('Y-m') == (string)($year).'-'.(string)($month-1))
//                        {
//                            // 先判断是不是已经写入了？
//                            $newslog = \app\admin\model\jdy\News::where('heyue_id', $heyue_row['id'])->where('type','工作提醒')
//                                ->where('lastdevicestarttime', strtotime(date('Y-m-d')))->find();
//                            // 如果为空
//                            if (!$newslog) {
//                                // 写入数据库
//                                $this->writeNewsheyue($heyue_row, 2);
//                            }
//                        }
//                    }
//                }
        }
        //echo "alarmheyue。。。。 finish!";
    }

    // http://localhost:9100//api/jdyalarm/fillstatistics
    // http://mg.acciot.com.tw/api/jdyalarm/fillstatistics
    // 统计表fa_jdy_statistics构建
    // 该API每天21:00（即第3个section的最后一刻）调用一次，只需要取前24小时内发生log的device
    public function fillstatistics()
    {
        set_time_limit(0); //执行时间无限
        ini_set('memory_limit', '-1'); //内存无限

        // 取当前时间前25小时时间段，本来是取24小时即可，但为了有些缓存，多取1个小时，然后用上面的三个时间段来判断
        //$currentdatePre1daytime = 1577538000;   // 测试1574438400代表2019-11-23 00:00:00
        $currentdatePre1daytime = strtotime(date('Y-m-d H:i:s', strtotime(date('Y-m-d',time()))-24*3600));

        // 1、取得所有的G设备的device。
        $sql = "select d.id as device_id, ac.id as anchang_id";
        $sql .= " from fa_jdy_device d inner join fa_jdy_anchang ac on d.room_id = ac.room_id";
        // 取得在时间段内所有的发生状态的devicelog
        $Alldevicelist = Db::query($sql);

        // 2、再取得在24小时时间段内所有的发生状态的devicelog，为了后面查找。按设备ID和发生时间升序排列，因为下限值的判断是24小时间隔
        $sql = "select device_id, online, starttime";
        $sql .= " from fa_jdy_devicelog";
        $sql .= " WHERE starttime >= $currentdatePre1daytime";
        $sql .= " ORDER BY device_id, starttime";
        // 取得在时间段内所有的发生状态的devicelog
        $AllPre24Hoursdevicelog_List = Db::query($sql);

        // 先把当前日期的三个时间段算出来
        // 目前有3段(1)21:00-04:59 (2)05:00-12:59、(3)13:00-20:59
        // section1是当前日期的零点向前减掉3个小时，即得到前天的21:00
        // section1是(1)21:00-04:59
        $section1_starttime = strtotime(date('Y-m-d H:i:s', strtotime(date('Y-m-d',time()))-24*3600));
        $section1_endtime = $section1_starttime + 8*3600;
        // section2是(2)05:00-12:59
        $section2_starttime = $section1_endtime;
        $section2_endtime = $section2_starttime + 8*3600;
        // section3是(3)13:00-20:59
        $section3_starttime = $section2_endtime;
        $section3_endtime = $section3_starttime + 8*3600;

        // 以下是要写入数据库的变量
        $whichsection = 1;      // 3段(1)21:00-04:59 (2)05:00-12:59、(3)13:00-20:59
        $onlinenum = 0;         // 在线次数
        $onlinemaxduration = 0; // 在线最长时间
        $onlineminduration = 0; // 在线最短时间
        $onlineaverageduration = 0; // 在线平均时长
        $offlinenum = 0;        // 离线次数
        $offlinemaxduration = 0;    // 离线最长时间
        $offlineminduration = 0;    // 离线最短时间
        $offlineaverageduration = 0;    // 离线平均时长

        $currentdeviceid = 0;   // 当前被处理的deviceid
        $predevicestatus = 0;     // 记录前一次的状态
        $pretimepoint = 0;      // 前一次的时间点，用于记录发生状态持续的时间长度
        $totalonlinetime = 0;   // 记录一个deviceid在一个时间section内，在线 发生的累积时间长度，为了后面计算平均值
        $totalofflinetime = 0;  // 记录一个deviceid在一个时间section内，离线 发生的累积时间长度，为了后面计算平均值
        // devicelog已经按device_id和发生状态的时间升序排序啦
        // devicelog表状态都应该是交互变化的，当前是在线，说明之前是离线，反之亦然，但也有例外，用 $predevicestatus 做例外处理
        foreach ($AllPre24Hoursdevicelog_List as $devicelog_row){
            if( $devicelog_row["starttime"] < $section1_starttime ||
                $devicelog_row["starttime"] > $section3_endtime )
            {
                // 不在当前判断的时间内
                continue;
            }

            if($currentdeviceid == $devicelog_row["device_id"])
            {
                // 发生状态时间点在第1个section(1)21:00-04:59内
                if( $devicelog_row["starttime"] >= $section1_starttime &&
                    $devicelog_row["starttime"] < $section1_endtime )
                {
                    $whichsection = 1;
                }
                // 发生状态时间点在第2个section(2)05:00-12:59内
                else if( $devicelog_row["starttime"] >= $section2_starttime &&
                    $devicelog_row["starttime"] < $section2_endtime )
                {
                    $whichsection = 2;
                }
                // 发生状态时间点在第3个section(3)13:00-20:59内
                else if( $devicelog_row["starttime"] >= $section3_starttime &&
                    $devicelog_row["starttime"] < $section3_endtime )
                {
                    $whichsection = 3;
                }

                // 更新状态
                if($devicelog_row["online"] == 1)   // 在线，之前是离线
                {
                    // 更新离线状态
                    if($predevicestatus == 0)
                    {
                        // 状态交替变化
                        $offlinenum++;
                        if($offlinemaxduration < ($devicelog_row["starttime"]-$pretimepoint))
                        {
                            $offlinemaxduration = $devicelog_row["starttime"]-$pretimepoint;
                        }
                        if($offlineminduration > ($devicelog_row["starttime"]-$pretimepoint))
                        {
                            $offlineminduration = $devicelog_row["starttime"]-$pretimepoint;
                        }
                        $totalofflinetime += $devicelog_row["starttime"]-$pretimepoint;
                    }
                    else
                    {
                        // 连续2次都是在线1
                        // 更新在线状态
                        $onlinenum++;
                        if($onlinemaxduration < ($devicelog_row["starttime"]-$pretimepoint))
                        {
                            $onlinemaxduration = $devicelog_row["starttime"]-$pretimepoint;
                        }
                        if($onlineminduration > ($devicelog_row["starttime"]-$pretimepoint))
                        {
                            $onlineminduration = $devicelog_row["starttime"]-$pretimepoint;
                        }
                        $totalonlinetime += $devicelog_row["starttime"]-$pretimepoint;
                    }
                }
                else    // 离线，之前是在线
                {
                    // 更新在线状态
                    if($predevicestatus == 1)
                    {
                        // 状态交替变化
                        $onlinenum++;
                        if($onlinemaxduration < ($devicelog_row["starttime"]-$pretimepoint))
                        {
                            $onlinemaxduration = $devicelog_row["starttime"]-$pretimepoint;
                        }
                        if($onlineminduration > ($devicelog_row["starttime"]-$pretimepoint))
                        {
                            $onlineminduration = $devicelog_row["starttime"]-$pretimepoint;
                        }
                        $totalonlinetime += $devicelog_row["starttime"]-$pretimepoint;
                    }
                    else
                    {
                        // 连续2次都是离线0
                        $offlinenum++;
                        if($offlinemaxduration < ($devicelog_row["starttime"]-$pretimepoint))
                        {
                            $offlinemaxduration = $devicelog_row["starttime"]-$pretimepoint;
                        }
                        if($offlineminduration > ($devicelog_row["starttime"]-$pretimepoint))
                        {
                            $offlineminduration = $devicelog_row["starttime"]-$pretimepoint;
                        }
                        $totalofflinetime += $devicelog_row["starttime"]-$pretimepoint;
                    }
                }
                $pretimepoint = $devicelog_row["starttime"];
            }
            else    // 不是同一个deviceid
            {
                // 先写入数据库
                if($onlinenum != 0 || $offlinenum != 0)
                {
                    // 计算平均值
                    if($onlinenum != 0)
                    {
                        $onlineaverageduration = $totalonlinetime / $onlinenum;
                    }
                    if($offlinenum != 0)
                    {
                        $offlineaverageduration = $totalofflinetime / $offlinenum;
                    }

                    $statisticslog = \app\admin\model\jdy\Statistics::where('device_id', $devicelog_row["device_id"])
                        ->where('statistics_datetime', date('Y-m-d'))->find();
                    // 如果为空，写入
                    if (!$statisticslog) {
                        // 已经赋值了，就要写入数据库
                        $devicelog_row["section"] = $whichsection;
                        $devicelog_row["statistics_datetime"] = date('Y-m-d');
                        $devicelog_row["onlinenum"] = $onlinenum;
                        $devicelog_row["onlinemaxduration"] = $onlinemaxduration;
                        $devicelog_row["onlineminduration"] = $onlineminduration;
                        $devicelog_row["onlineaverageduration"] = $onlineaverageduration;
                        $devicelog_row["offlinenum"] = $offlinenum;
                        $devicelog_row["offlinemaxduration"] = $offlinemaxduration;
                        $devicelog_row["offlineminduration"] = $offlineminduration;
                        $devicelog_row["offlineaverageduration"] = $offlineaverageduration;
                        // 对应案场ID
                        foreach ($Alldevicelist as $device_row) {
                            if($devicelog_row["device_id"] == $device_row["device_id"])
                            {
                                // 取出案场ID
                                $devicelog_row["anchang_id"] = $device_row["anchang_id"];
                                break;
                            }
                        }
                        // 判断24小时内没有重复的
                        $this->writestatistics($devicelog_row);
                    }
                }

                // 清空变量
                // 确认第一条记录的时间点是在哪个时间段
                if( $devicelog_row["starttime"] >= $section1_starttime &&
                    $devicelog_row["starttime"] < $section1_endtime )
                    $pretimepoint = $section1_starttime;
                else if( $devicelog_row["starttime"] >= $section2_starttime &&
                    $devicelog_row["starttime"] < $section2_endtime )
                    $pretimepoint = $section2_starttime;
                else if( $devicelog_row["starttime"] >= $section3_starttime &&
                    $devicelog_row["starttime"] < $section3_endtime )
                    $pretimepoint = $section3_starttime;
                else
                    $pretimepoint = $devicelog_row["starttime"];

                if($devicelog_row["online"] == 1)
                {
                    $onlinenum = 1;         // 在线次数
                    $onlinemaxduration = $devicelog_row["starttime"]-$pretimepoint; // 在线最长时间
                    $onlineminduration = $onlinemaxduration; // 在线最短时间，第一次和最大相同
                    $onlineaverageduration = 0; // 在线平均时长
                    $totalonlinetime = $onlinemaxduration;   // 第一次和最大相同
                    // 离线的都清空
                    $offlinenum = 0;        // 离线次数
                    $offlinemaxduration = 0;    // 离线最长时间
                    $offlineminduration = 0;    // 离线最短时间
                    $offlineaverageduration = 0;    // 离线平均时长
                    $totalofflinetime = 0;   // 第一次和最大相同
                }
                else
                {
                    $offlinenum = 1;        // 离线次数
                    $offlinemaxduration = $devicelog_row["starttime"]-$pretimepoint; // 离线最长时间
                    $offlineminduration = $offlinemaxduration;    // 离线最短时间
                    $offlineaverageduration = 0;    // 离线平均时长
                    $totalofflinetime = $offlinemaxduration;   // 第一次和最大相同
                    // 在线的都清空
                    $onlinenum = 0;         // 在线次数
                    $onlinemaxduration = 0; // 在线最长时间
                    $onlineminduration = 0; // 在线最短时间，第一次和最大相同
                    $onlineaverageduration = 0; // 在线平均时长
                    $totalonlinetime = 0;   // 第一次和最大相同
                }

                // 下一个要处理的deviceid
                $currentdeviceid = $devicelog_row["device_id"];
                $predevicestatus = $devicelog_row["online"];
            }
        }
        echo "fillstatistics function finished!";
        return;
    }

    // 写入fa_jdy_statistics统计信息
    public function writestatistics($row){
        $statistics = new \app\admin\model\jdy\Statistics();

        $statistics->anchang_id = $row["anchang_id"];
        $statistics->device_id = $row["device_id"];
        $statistics->section = $row["section"];
        $statistics->statistics_datetime = $row["statistics_datetime"];
        $statistics->onlinenum = $row["onlinenum"];
        $statistics->onlinemaxduration = $row["onlinemaxduration"];
        $statistics->onlineminduration = $row["onlineminduration"];
        $statistics->onlineaverageduration = $row["onlineaverageduration"];
        $statistics->offlinenum = $row["offlinenum"];
        $statistics->offlinemaxduration = $row["offlinemaxduration"];
        $statistics->offlineminduration = $row["offlineminduration"];
        $statistics->offlineaverageduration = $row["offlineaverageduration"];
        $statistics->create_time = date('Y-m-d H:i:s');
        // 写入
        $statistics->save();
    }

    // 写入fa_jdy_news工作提醒
    /*
     * 工作狀態”工作狀態”、 標題”工作標題”、 案場”案場名稱”、 提醒日期”工作日期”
     */
    public function writeNewstask($row){
        $news = new \app\admin\model\jdy\News();

        //依工作事项设定日期，对相关人员发出到最新消息，提醒内容:
        //提醒类型: 工作提醒
        //您有工作事项提醒：”案场名称”、”标题”、”工作状态”!
        $news->task_id = $row["id"];
        $news->anchang_id = $row["anchang_id"];
        $news->lastdevicestarttime = strtotime($row["alarmtime"]);
        $news->name = "工作狀態\"" . $row['task_status'] . "\"、標題\"" . $row['title'] . "\"、案場\"" . $row['acname'] .
            "\"、提醒日期\"". $row['remind_date'] . "\"！";
        $news->create_time = date('Y-m-d H:i:s');
        $news->type = "工作提醒";

        $news->save();
    }

    // 写入fa_jdy_news合约提醒
    // 输入参数$formattype:
    // 1、合约建立工作提醒
    // 2、合约到期前提醒
    public function writeNewsheyue($row, $formattype){
        $news = new \app\admin\model\jdy\News();

        //依工作事项设定日期，对相关人员发出到最新消息，提醒内容:
        //提醒类型: 工作提醒
        //您有工作事项提醒：”案场名称”、”标题”、”工作状态”!
        if($formattype == 1)    // 合约建立工作提醒
        {
            $news->name = "您有需安排工作事項提醒：" . "案場\"" . $row['acname'] . "\"、合约编号\"" . $row['contract_no']
                . "\"、合约即将開始日期\"". $row['remind_start_date'] . "\"，該案場合約即將開始！"
                . "\"、服務周期\"按". $row['service_cycle'] . "\"、服務次數\"" . $row['times'] . "次\""
                . "\"、服務人數\"" . $row['mans'] . "人\"、" . "服務時間\"" . $row['service_hours'] . "\"的養護工作安排！";
        }
        else if($formattype == 2)    // 合约到期前提醒
        {
            $news->name = "您有需安排工作事項提醒：" . "案場\"" . $row['acname'] . "\"、合約編號\"" . $row['contract_no']
                . "\"、合约即将到期日期\"". $row['remind_end_date'] . "\"，該案場合約即將到期！";
        }

        // 写入公共部分
        $news->heyue_id = $row["id"];
        $news->anchang_id = $row["anchang_id"];
        $news->lastdevicestarttime = strtotime(date('Y-m-d'));
        $news->create_time = date('Y-m-d H:i:s');
        $news->type = "工作提醒";

        $news->save();
    }

    // 写入fa_jdy_news即时信息
    public function writeNewsJS($row){
        $news = new \app\admin\model\jdy\News();
        // 提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號] [裝置狀態]
        // 例如：2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟A泵浦狀態監視 [清CAG] 離線
        $news->device_id = $row["deviceid"];
        $news->anchang_id = $row["anchang_id"];
        $news->lastdevicestarttime = $row["online_starttime"];
        $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname']."[".$row['devicename']."]".$row['warning_status'];
        $news->create_time = date('Y-m-d H:i:s');
        $news->type = "裝置狀態";

        $news->save();

        $maintenance = new \app\admin\model\jdy\Maintenance;
        $maintenance->anchang_id = $news->anchang_id;
        $maintenance->content = "裝置狀態 [{$news->name}]";
        $maintenance->save();
    }

    // 写入fa_jdy_news延时信息
    // 输入参数$section：0-> 05:00:00调用   1-> 13:00:00调用  2-> 21:00:00调用
    // 输入参数formattype：写入格式，
    //      -1：代表是最普通的延时播报
    //      0：代表未达标准值，
    //      1：代表低于下限值，
    //      2：代表超过上限值，
    //      3：代表运转不足，即在线时间有一次未达到在线时间段，
    //      4：代表待机不足，即离线时间有一次未达到离线的时间段
    //      5：R设备2个对应设备未同步
    //      6：R设备只有1个对应设备未同步
    // 输入参数num：次数
    public function writeNewsYS($row, $section, $formattype, $num){
        $news = new \app\admin\model\jdy\News();
        if($formattype == 0)
        {
            //指定日期-未達標準值告警:
            //提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號] [時段] 未達標準值[次數]
            //例如: 2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟A泵浦狀態監視 [清CAG]在線[05:00-12:59] 未達標準值 2次
            if($section == 0)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[21:00-04:59]"."未達標準值 ".$num."次";
            else if($section == 1)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[05:00-12:59]"."未達標準值 ".$num."次";
            else //if($section == 2)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[13:00-20:59]"."未達標準值 ".$num."次";
        }
        else if($formattype == 1) {
            // 指定日期-未達下限值告警:alarmjs
            // 提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號] [時段] 未達下限值[次數]
            // 例如: 2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟A泵浦狀態監視[清CAG]在線[时间段]未達下限值 2次
            if($section == 0)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[21:00-04:59]"."未達下限值 ".$num."次";
            else if($section == 1)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[05:00-12:59]"."未達下限值 ".$num."次";
            else //if($section == 2)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[13:00-20:59]"."未達下限值 ".$num."次";
        }
        else if($formattype == 2) {
            // 指定日期-超過上限值告警:
            // 提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號] [時段] 超過上限值[次數]
            // 例如: 2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟A泵浦狀態監視[清CAG]在線[05:00-12:59]超過上限值[2次]
            if($section == 0)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[21:00-04:59]"."超過上限值 ".$num."次";
            else if($section == 1)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[05:00-12:59]"."超過上限值 ".$num."次";
            else //if($section == 2)
                $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                    "[".$row['devicename']."]".$row['warning_status']."[13:00-20:59]"."超過上限值 ".$num."次";
        }
        else if($formattype == 3) {
            // 指定日期-運轉不足:
            // 提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號]運轉不足
            // 例如: 2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟A泵浦狀態監視 [清CAG]在線 運轉超時
            $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                "[".$row['devicename']."]".$row['warning_status']." 運轉不足";
        }
        else if($formattype == 4) {
            // 指定日期-未啟動/待機不足:
            // 提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號]未啟動/待機不足
            // 例如: 2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟A泵浦狀態監視 [清CAG]在線 未啟動
            $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                "[".$row['devicename']."]".$row['warning_status']." 未啟動";
        }
        else if($formattype == 5) {
            // 提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號] [裝置狀態][關聯裝置代號1][關聯裝置狀態][關聯裝置代號2] [關聯裝置2狀態]運作未同步
            //例如: 2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟啟動液面 [清CR]在線 [清CAG]離線[清CBG]離線 運作未同步
            $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                "[".$row['devicename']."]".$row['warning_status']."[".$row["device1_name"]."]".$row["device1_status"].
                "[".$row["device2_name"]."]".$row["device2_status"]." 運作未同步";
        }
        else if($formattype == 6) {
            // 提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號] [裝置狀態][關聯裝置代號1][關聯裝置狀態]運作未同步
            //例如: 2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟啟動液面 [清CR]在線 [清CAG]離線 運作未同步
            $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname'].
                "[".$row['devicename']."]".$row['warning_status']."[".$row["device1_name"]."]".$row["device1_status"]." 運作未同步";
        }
        else
        {
            // 其他情况就是最普通的报警
            // 提醒內容: [日期 時間][案場名稱]:[裝置名稱] [裝置代號] [裝置狀態]
            // 例如：2019-11-27 09:55:33 [新北林口紐約上城] 揚水C棟A泵浦狀態監視 [清CAG] 離線
            $news->name = date('Y-m-d H:i:s')."[".$row['acname']."]".$row['deviceselfname']."[".$row['devicename']."]".$row['warning_status'];
        }

        // 以下是公共部分
        $news->device_id = $row['deviceid'];
        $news->anchang_id = $row["anchang_id"];
        $news->type = "裝置狀態";
        $news->lastdevicestarttime = $row['online_starttime'];
        $news->create_time = date('Y-m-d H:i:s');
        // 写入
        $news->save();

        $maintenance = new \app\admin\model\jdy\Maintenance;
        $maintenance->anchang_id = $news->anchang_id;
        $maintenance->content = "裝置狀態 [{$news->name}]";
        $maintenance->save();
    }
}